﻿using AutoMapper;
using BackData;
using Domain.BOM;
using Domain.DTOs.BOMs;
using Infratructure;
using MediatR;
using Team.API.Applocation.Command.BOM;


namespace Team.API.Applocation.Hanldler.BOM
{
    public class GetBOMTreeHandler:IRequestHandler<GetBOMTreeCommand, APIResult<List< BOMDTO>>>
    {
        private readonly IRepository<Bomtable> bomway;
        private readonly IMapper mapper;
        private readonly ILogger<GetBOMHandler> log;

        public GetBOMTreeHandler(IRepository<Bomtable> bomway, IMapper mapper, ILogger<GetBOMHandler> log)
        {
            this.bomway = bomway;
            this.mapper = mapper;
            this.log = log;
        }

        /// <summary>
        /// 获取物料清单树结构
        /// 根据ProductId或RootParentId隔离数据，确保每个成品的数据独立
        /// </summary>
        /// <param name="request"></param>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        public async Task<APIResult<List<BOMDTO>>> Handle(GetBOMTreeCommand request, CancellationToken cancellationToken)
        {
            var res = new APIResult<List<BOMDTO>>();
            
            try
            {
                string rootParentId = "F0";
                long? productIdForIsolation = null;
                
                // 如果指定了RootParentId，使用它作为根节点
                if (!string.IsNullOrWhiteSpace(request.RootParentId))
                {
                    rootParentId = request.RootParentId;
                    // 如果同时指定了ProductId，用于数据隔离
                    if (request.ProductId.HasValue && request.ProductId.Value > 0)
                    {
                        productIdForIsolation = request.ProductId.Value;
                    }
                }
                // 如果指定了ProductId，获取该成品的ChildrenId作为根节点
                else if (request.ProductId.HasValue && request.ProductId.Value > 0)
                {
                    // 使用异步方法获取成品BOM
                    var productBOM = await bomway.GetByIdAsync(request.ProductId.Value);
                    if (productBOM != null && !productBOM.IsDel)
                    {
                        // 如果成品有ChildrenId，使用它；否则使用"F0"
                        rootParentId = !string.IsNullOrWhiteSpace(productBOM.ChildrenId) ? productBOM.ChildrenId : "F0";
                        productIdForIsolation = request.ProductId.Value;
                    }
                }

                // 获取树形结构，如果指定了ProductId则只显示当前成品下的数据
                // 使用版本参数进行查询（如果提供了版本）
                var list = await GetTreeAsync(rootParentId, productIdForIsolation, request.Version);
                
                if (list != null && list.Count > 0)
                {
                    res.Message = "获取成功";
                    res.Result = list;
                    res.Code = StateCode.OK;
                }
                else
                {
                    res.Message = "未找到数据";
                    res.Code = StateCode.OK;
                    res.Result = new List<BOMDTO>();
                }
            }
            catch (Exception ex)
            {
                log.LogError(ex, "获取BOM树结构时发生错误");
                res.Message = "获取失败：" + ex.Message;
                res.Code = StateCode.Fail;
                res.Result = null;
            }

            return res;
        }

        /// <summary>
        /// 递归获取树形结构（异步版本）
        /// 根据parentid递归查找子节点，实现树形结构
        /// 如果指定了ProductId，只返回属于该成品的数据，实现数据隔离
        /// 如果指定了Version，只返回匹配版本的数据
        /// </summary>
        /// <param name="parentid">父级ID</param>
        /// <param name="productId">成品ID（用于数据隔离，可选）</param>
        /// <param name="version">版本号（用于版本过滤，可选）</param>
        /// <returns>树形结构列表</returns>
        private async Task<List<BOMDTO>> GetTreeAsync(string parentid, long? productId = null, string version = null)
        {
            // 构建查询条件：根据parentid查找子节点（使用SqlSugar语法）
            var query = bomway.GetAll()
                .Where(x => x.Parentid == parentid && x.IsDel == false);

            // 如果指定了版本，添加版本查询条件
            if (!string.IsNullOrWhiteSpace(version))
            {
                query = query.Where(x => x.Version == version);
            }

            // 如果指定了ProductId，需要确保只获取属于该成品的数据
            if (productId.HasValue && productId.Value > 0)
            {
                // 获取该成品BOM（使用异步方法）
                var productBOM = await bomway.GetByIdAsync(productId.Value);
                if (productBOM != null && !productBOM.IsDel)
                {
                    var productChildrenId = productBOM.ChildrenId;
                    
                    // 如果成品没有ChildrenId，使用"F0"作为根节点
                    if (string.IsNullOrWhiteSpace(productChildrenId))
                    {
                        productChildrenId = "F0";
                    }
                    
                    // 如果当前parentid就是成品的ChildrenId，说明是根节点，直接查询
                    // 否则需要确保该parentid属于该成品的子树
                    if (parentid != productChildrenId)
                    {
                        // 验证parentid是否属于该成品的子树
                        // 通过查找parentid对应的节点，检查其祖先链是否最终指向成品的ChildrenId
                        if (!await IsChildOfProductAsync(parentid, productChildrenId))
                        {
                            // 不属于该成品，返回空列表
                            return new List<BOMDTO>();
                        }
                    }
                }
                else
                {
                    // 成品不存在或已删除，返回空列表
                    return new List<BOMDTO>();
                }
            }

            // 执行查询并转换为列表（SqlSugar语法，使用异步版本）
            var list = await query.ToListAsync();
            var result = mapper.Map<List<BOMDTO>>(list);
            
            // 递归获取子节点（异步）
            foreach (var item in result)
            {
                if (!string.IsNullOrWhiteSpace(item.ChildrenId))
                {
                    item.Children = await GetTreeAsync(item.ChildrenId, productId, version);
                }
            }
            
            return result;
        }

        /// <summary>
        /// 检查指定的parentid是否属于指定成品的子树（异步版本）
        /// 通过查找parentid对应的节点，检查其祖先链是否最终指向productChildrenId
        /// </summary>
        /// <param name="parentid">要检查的父级ID</param>
        /// <param name="productChildrenId">成品的ChildrenId</param>
        /// <returns>如果属于该成品的子树返回true，否则返回false</returns>
        private async Task<bool> IsChildOfProductAsync(string parentid, string productChildrenId)
        {
            if (string.IsNullOrWhiteSpace(parentid) || string.IsNullOrWhiteSpace(productChildrenId))
            {
                return false;
            }

            // 如果parentid就是productChildrenId，直接返回true
            if (parentid == productChildrenId)
            {
                return true;
            }

            // 查找parentid对应的BOM记录（通过ChildrenId查找，因为parentid是某个节点的ChildrenId）
            // 使用SqlSugar的FirstAsync方法（异步版本），如果找不到返回null
            var bomList = await bomway.GetAll()
                .Where(x => x.ChildrenId == parentid && x.IsDel == false)
                .ToListAsync();
            var bom = bomList.FirstOrDefault();
            
            if (bom == null)
            {
                // 如果找不到对应的节点，说明parentid可能是根节点"F0"或其他未使用的ID
                // 在这种情况下，如果parentid等于productChildrenId，返回true；否则返回false
                return parentid == productChildrenId;
            }

            // 如果该记录的Parentid是productChildrenId，说明属于该成品
            if (bom.Parentid == productChildrenId)
            {
                return true;
            }

            // 递归检查父级，但需要防止无限递归（异步）
            if (!string.IsNullOrWhiteSpace(bom.Parentid) && bom.Parentid != parentid)
            {
                return await IsChildOfProductAsync(bom.Parentid, productChildrenId);
            }

            return false;
        }
    }
}

